#ifndef _BUFFER_MANAGER_H_
#define _BUFFER_MANAGER_H_

#include "PageTable.h"
#include "Histogram.h"
#include <fstream>
#include <iostream>

using namespace std;

#define TIMERATIO 0.5
#define RANGERATIO (1.0 - TIMERATIO)

typedef struct BufEntry
{
	void * pointer; // pointer to the page
	int nodeId;     // page id
	long last_time; // last access time
	bool dirtyBit;  // flag of dirty
	bool memBit;    // in memory now
} BufEntry;

class BufferManager
{
public:
	BufferManager(int mId, int mSize, int pSize, int w, int s, int bt);
	~BufferManager();

	int RequestID();
	bool AddEntry(void* pointer, int id);

	void LoadUpdate(int id);
	void ReadUpdate(int id);
	void WriteUpdate(int id);
	void SaveUpdate(int id);

	bool isDirty(int id);
	bool CopyFromDisk(int id, char* buffer);
	bool SaveToDisk(int id, char* buffer);
	long GetReadIO(){return readIO;};
	long GetWriteIO(){return writeIO;};
	int GetCurrentID(){return currentId;};

	// statistics
	long readIO;
	long writeIO;

	Histogram * his;

private:
	fstream diskfile;       // file on disk
	BufEntry * entryArray;  // array of entries
	PageTable * ptable;     // page table
	int * activeEntry;      // node id of active entries

	int pageSize;           // page size by byte
	int maxId;              // max number of node
	int maxSize;            // max size of the active entry by page
	int currentSize;        // current size of the active entry
	int currentId;          // next id
	long updateTime;        // update time
	long totalupdate;       // for new replacement algorithm
	int buffertype;         // buffer type

	int PickupSaveEntry(int curID); // page replacement least recently used
	int NewPickupSaveEntry(int curID, double timeratio, double rangeratio);  // new page replacement considering range ratio
};

#endif
